/*
 * syntactic.c
 *
 * Version 1.0
 * Author: rtp
 *
 * Description: syntactic analyzer (parser)
 *
 */

#include<stdlib.h>
#include<stdio.h>

#include "semantic.h"
#include "syntactic.h"
#include "lexical.h"
#include "token.h"

boolean comando(Token t);
boolean bloco();
boolean exp(Token t);
boolean expprefixo(Token t);
boolean args(Token t);

boolean syn_analyse(char* srcFile, char* objFile) {
	printf("1\n");
	lx_init();
	printf("2\n");
	lx_setFile(srcFile);
	printf("3\n");

	sem_init(objFile);

	if (programa()) {
		printf("Compilation successful!\n");
	} else {
		printf("Compilation time ERROR:\n");
	}

	printf(".4\n");
	lx_closeFile();
	sem_finaliza();
	return TRUE;
}

boolean bloco() {
	int state = 0;
	Token t;
	//printf("3.0.0 bloco\n");

	while ((t = lx_getToken()) != NULL) {
		printf("bloco(%d)\n", state);

		switch (state) {
		case 0:
			if (comando(t) == FALSE) {
				state = 1;
				break;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("return")) {
					state = 2;
					break;
				}
				if (t->index == hash_function("break")) {
					state = 3;
					break;
				}
			}
			return FALSE;
			break;
		case 1:
			if (comando(t) == TRUE)
				break;
			return TRUE;
			break;
		case 2:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(";")) {
					state = 5;
					break;
				}

			}
			if (exp(t))
				state = 6;
			else
				return TRUE;
			break;
		case 3:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(";")) {
					state = 5;
				}
			} else
				return TRUE;
			break;
		case 4:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("return")) {
					state = 2;
					break;
				}
				if (t->index == hash_function("break")) {
					state = 3;
					break;
				}
			}
			if (comando(t))
				state = 1;
			else
				return TRUE;
			break;
		case 5:
			return TRUE;
			break;
		case 6:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(";")) {
					state = 7;
				}
			} else
				return TRUE;
			break;
		case 7:
			if (exp(t))
				state = 6;
			else
				return FALSE;
			break;
		}
		t = lx_getToken();
	}
	return FALSE;
}

boolean args(Token t) {
	//printf("3.0.2 args\n");
	int state = 0;
	while (t != NULL) {
		printf("args state(%d)\n", state);
		switch (state) {
		case 0:
			if (t->type == TK_CADEIA) {
				state = 3;
				break;
			}
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("{")) {
					state = 1;
				}
				if (t->index == hash_function("(")) {
					state = 2;
				}
			} else
				return FALSE;
			break;
		case 1:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")")) {
					state = 3;
					break;
				}
			}
			if (exp(t))
				state = 4;
			else
				return FALSE;
			break;
		case 2:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("[")) {
					state = 6;
					break;
				}
			} else if (t->type == TK_IDENTIFIER) {
				state = 7;
				break;
			} else if (exp(t)) {
				state = 5;
			} else
				return FALSE;
			break;
		case 3:
			return TRUE;
			break;
		case 4:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(";")) {
					state = 8;
					break;
				}
				if (t->index == hash_function(")")) {
					state = 3;
					break;
				}
			} else
				return FALSE;
			break;
		case 5:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(";")) {
					state = 2;
					break;
				}
				if (t->index == hash_function(",")) {
					state = 8;
					break;
				}
				if (t->index == hash_function("}")) {
					state = 3;
					break;
				}
			} else
				return FALSE;
			break;
		case 6:
			if (exp(t)) {
				state = 10;
			} else
				return FALSE;
			break;
		case 7:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("=")) {
					state = 9;
					break;
				}
			} else
				return FALSE;
			break;
		case 8:
			if (exp(t)) {
				state = 4;
			} else
				return FALSE;
			break;
		case 9:
			if (exp(t)) {
				state = 5;
			} else
				return FALSE;
			break;
		case 10:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("]")) {
					state = 7;
					break;
				}
			} else
				return FALSE;
			break;
		}
		t = lx_getToken();
	}
	return FALSE;
}

boolean expprefixo(Token t) {
	//printf("3.0.3 expprefixo\n");

	int state = 0;
	while (t != NULL) {
		printf("expprefixo state(%d)\n", state);
		switch (state) {
		case 0:
			if (t->type == TK_IDENTIFIER) {
				state = 1;
				//				sem_PushId(t->value);
			} else if (t->type == TK_SINAL) {
				if (t->index == hash_function("("))
					state = 2;
			} else
				return FALSE;
			break;
		case 1:
			if (args(t))
				break;
			else if (t->type == TK_SINAL) {
				if (t->index == hash_function("."))
					state = 4;
				else if (t->index == hash_function(":"))
					state = 5;
			} else
				return TRUE;
			break;
		case 2:
			if (exp(t))
				state = 6;
			else
				return FALSE;
			break;
		case 3:
			if (exp(t))
				state = 8;
			else
				return FALSE;
			break;
		case 4:
			if (tipo(t) == TK_IDENTIFIER) {
				state = 1;
			} else
				return FALSE;
			break;
		case 5:
			if (tipo(t) == TK_IDENTIFIER) {
				state = 7;
			} else
				return FALSE;
			break;
		case 6:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")"))
					state = 1;
			} else
				return FALSE;
			break;
		case 7:
			if (args(t))
				state = 1;
			else
				return FALSE;
			break;
		case 8:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("]"))
					state = 1;
			} else
				return FALSE;
			break;
		}
		t = lx_getToken();
	}
	return FALSE;
}

boolean exp(Token t) {
	int state = 0;
	Token t;
	//printf("3.0.0 bloco\n");

	while (t != NULL) {
		printf("exp(%d)\n", state);

		switch (state) {
		case 0:
			if (expprefixo(t) == TRUE) {
				state = 1;
				break;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("...")) {
					state = 1;
					break;
				}
				if (t->index == hash_function("function")) {
					state = 2;
					break;
				}
				if (t->index == hash_function("not")) {
					state = 4;
					break;
				}
			} else if (t->type == TK_NUMBER) {
				state = 1;
				break;
			} else if (t->type == TK_CADEIA) {
				state = 1;
				break;
			} else if (t->type == TK_SINAL) {
				if (t->index == hash_function("{")) {
					state = 3;
					break;
				} else if (t->index == hash_function("-")) {
					state = 4;
					break;
				} else if (t->index == hash_function("#")) {
					state = 4;
					break;
				}
			}
			return FALSE;
			break;
		case 1:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("and")) {
					state = 4;
					break;
				}
				if (t->index == hash_function("or")) {
					state = 4;
					break;
				}
			} else if (t->type == TK_SINAL) {
				if (t->index == hash_function("+")) {
					state = 4;
					break;
				} else if (t->index == hash_function("-")) {
					state = 4;
					break;
				} else if (t->index == hash_function("*")) {
					state = 4;
					break;
				} else if (t->index == hash_function("/")) {
					state = 4;
					break;
				} else if (t->index == hash_function("^")) {
					state = 4;
					break;
				} else if (t->index == hash_function("%")) {
					state = 4;
					break;
				} else if (t->index == hash_function("..")) {
					state = 4;
					break;
				} else if (t->index == hash_function("<")) {
					state = 4;
					break;
				} else if (t->index == hash_function(">")) {
					state = 4;
					break;
				}
			}
			return FALSE;
			break;
		case 2:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("(")) {
					state = 10;
					break;
				}

			} else
				return FALSE;
			break;
		case 3:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("[")) {
					state = 6;
				} else if (t->index == hash_function("}")) {
					state = 1;
				}
			} else if (t->type == TK_IDENTIFIER) {
				state = 5;
				break;
			} else if (exp(t))
				state = 7;
			else
				return TRUE;
			break;
		case 4:
			if (exp(t))
				state = 1;
			else
				return TRUE;
			break;
		case 5:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("=")) {
					state = 9;
				}
			} else
				return FALSE;
			break;
		case 6:
			if (exp(t))
				state = 8;
			else
				return FALSE;
			break;
		case 7:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(",")) {
					state = 3;
				} else if (t->index == hash_function(";")) {
					state = 3;
				} else if (t->index == hash_function("}")) {
					state = 1;
				}
			} else
				return FALSE;
			break;
		case 8:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("]")) {
					state = 5;
				}
			} else
				return FALSE;
			break;
		case 9:
			if (exp(t))
				state = 7;
			else
				return FALSE;
			break;
		case 10:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")")) {
					state = 13;
				}
			} else if (t->type == TK_IDENTIFIER) {
				state = 12;
			} else if (t->index == hash_function("...")) {
				state = 11;
			} else
				return FALSE;
			break;
		case 11:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")")) {
					state = 13;
				}
			} else
				return FALSE;
			break;
		case 12:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(",")) {
					state = 15;
				} else if (t->index == hash_function(")")) {
					state = 13;
				}
			} else
				return FALSE;
			break;
		case 13:
			if (bloco(t)) {
				state = 14;
			} else
				return FALSE;
			break;
		case 14:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("end"))
					state = 1;
			} else
				return FALSE;
			break;
		case 15:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("..."))
					state = 11;
			} else if (t->type == TK_IDENTIFIER)
				state = 12;
			else
				return FALSE;
			break;

		}
		t = lx_getToken();
	}
	return FALSE;
}

boolean comando(Token t) {
	int state = 0;
	Token t;
	//printf("3.0.0 bloco\n");

	while (t != NULL) {
		printf("exp(%d)\n", state);

		switch (state) {
		case 0:
			if (expprefixo(t)) {
				state = 2;
				break;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("do")) {
					state = 3;
					break;
				}
				if (t->index == hash_function("while")) {
					state = 4;
					break;
				}
				if (t->index == hash_function("repeat")) {
					state = 5;
					break;
				}
				if (t->index == hash_function("if")) {
					state = 6;
					break;
				}
				if (t->index == hash_function("for")) {
					state = 7;
					break;
				}
				if (t->index == hash_function("function")) {
					state = 8;
					break;
				}
				if (t->index == hash_function("local")) {
					state = 9;
					break;
				}
			} else if (t->type == TK_IDENTIFIER) {
				state = 1;
				break;
			}
			return FALSE;
			break;
		case 1:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(",")) {
					state = 10;
					break;
				}
				if (t->index == hash_function("=")) {
					state = 11;
					break;
				}
			}
			return FALSE;
			break;
		case 2:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("[")) {
					state = 21;
					break;
				}
				if (t->index == hash_function(".")) {
					state = 22;
					break;
				}
				if (t->index == hash_function(":")) {
					state = 26;
					break;
				}

			} else if (args(t))
				state = 23;
			else
				return FALSE;
			break;
		case 3:
			if (bloco(t))
				state = 20;
			else
				return FALSE;
			break;
		case 4:
			if (exp(t))
				state = 30;
			else
				return FALSE;
			break;
		case 5:
			if (exp(t))
				state = 31;
			else
				return FALSE;
			break;
		case 6:
			if (exp(t))
				state = 34;
			else
				return FALSE;
			break;
		case 7:
			if (t->type == TK_IDENTIFIER) {
				state = 33;
			} else
				return FALSE;
			break;
		case 8:
			if (t->type == TK_IDENTIFIER) {
				state = 29;
			} else
				return FALSE;
			break;
		case 9:
			if (t->type == TK_IDENTIFIER) {
				state = 12;
			} else if (t->index == hash_function("function"))
				state = 13;
			else
				return FALSE;
			break;
		case 10:
			if (t->type == TK_IDENTIFIER) {
				state = 1;
			} else if (expprefixo(t))
				state = 19;
			else
				return FALSE;
			break;
		case 11:
			if (exp(t)) {
				state = 14;
			} else
				return FALSE;
			break;
		case 12:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(",")) {
					state = 27;
				} else if (t->index == hash_function("=")) {
					state = 11;
				}
			} else
				return TRUE;
			break;
		case 13:
			if (t->type == TK_IDENTIFIER) {
				state = 15;
			} else
				return FALSE;
			break;
		case 14:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 11;
			} else
				return TRUE;
			break;
		case 15:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("("))
					state = 16;
			} else
				return FALSE;
			break;
		case 16:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")"))
					state = 3;
			} else if (t->type == TK_IDENTIFIER)
				state = 17;
			else if (t->index == hash_function("..."))
				state = 18;
			else
				return FALSE;
			break;

		case 17:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 25;
				else if (t->index == hash_function(")"))
					state = 3;
			} else
				return FALSE;
			break;
		case 18:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(")"))
					state = 3;
			} else
				return FALSE;
			break;
		case 19:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("["))
					state = 21;
				else if (t->index == hash_function("."))
					state = 22;
			} else
				return FALSE;
			break;
		case 20:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("end"))
					state = 23;
			} else
				return FALSE;
			break;
		case 21:
			if (exp(t)) {
				state = 24;
			} else
				return FALSE;
			break;
		case 22:
			if (t->type == TK_IDENTIFIER) {
				state = 1;
			} else
				return FALSE;
			break;
		case 23:
			return TRUE;
			break;
		case 24:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("]"))
					state = 1;
			} else
				return FALSE;
			break;
		case 25:
			if (t->type == TK_IDENTIFIER) {
				state = 17;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("..."))
					state = 18;
			} else
				return FALSE;
			break;
		case 26:
			if (t->type == TK_IDENTIFIER) {
				state = 28;
			} else
				return FALSE;
			break;
		case 27:
			if (t->type == TK_IDENTIFIER) {
				state = 12;
			} else
				return FALSE;
			break;
		case 28:
			if (args(t)) {
				state = 23;
			} else
				return FALSE;
			break;
		case 29:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("."))
					state = 8;
				else if (t->index == hash_function(":"))
					state = 13;
				else if (t->index == hash_function("("))
					state = 16;
			} else
				return FALSE;
			break;
		case 30:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("do"))
					state = 3;
			} else
				return FALSE;
			break;
		case 31:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("until"))
					state = 32;
			} else
				return FALSE;
			break;
		case 32:
			if (exp(t)) {
				state = 23;
			} else
				return FALSE;
			break;
		case 33:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 35;
				else if (t->index == hash_function("="))
					state = 36;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("in"))
					state = 37;
			} else
				return FALSE;
			break;
		case 34:
			if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("then"))
					state = 38;
			} else
				return FALSE;
			break;
		case 35:
			if (t->type == TK_IDENTIFIER) {
				state = 44;
			} else
				return FALSE;
			break;
		case 36:
			if (exp(t)) {
				state = 41;
			} else
				return FALSE;
			break;
		case 37:
			if (exp(t)) {
				state = 39;
			} else
				return FALSE;
			break;
		case 38:
			if (bloco(t)) {
				state = 40;
			} else
				return FALSE;
			break;
		case 39:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 37;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("do"))
					state = 3;
			} else
				return FALSE;
			break;
		case 40:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function("end"))
					state = 23;
				else if (t->index == hash_function("elseif"))
					state = 6;
				else if (t->index == hash_function("else"))
					state = 3;
			} else
				return FALSE;
			break;
		case 41:
			if (exp(t)) {
				if (t->index == hash_function(","))
					state = 42;
			} else
				return FALSE;
			break;
		case 42:
			if (exp(t)){
				state = 43;
			} else
				return FALSE;
			break;
		case 43:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 4;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("do"))
					state = 3;
			} else
				return FALSE;
			break;
		case 44:
			if (t->type == TK_SINAL) {
				if (t->index == hash_function(","))
					state = 35;
			} else if (t->type == TK_RESEVED_WORD) {
				if (t->index == hash_function("in"))
					state = 37;
			} else
				return FALSE;
			break;
		}

		t = lx_getToken();
	}
	return FALSE;
}
